home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / cenvid / batch.cmm < prev    next >
Text File  |  1995-10-11  |  21KB  |  796 lines

  1. /*
  2.  * Batch.cmm
  3.  *
  4.  *   Interpret a DOS batch file using CEnvi. This should work on all CEnvi
  5.  *   versions.
  6.  */
  7.  
  8. /* ---------------------------------------------------------------------- */
  9.  
  10. usage()
  11. {
  12.   printf("Use the BATCH command to interpret a DOS batch file under any system\n");
  13.   printf("that CEnvi supports.\n");
  14.   printf("Syntax:\n  BATCH [filename] [args]\nwhere:\n");
  15.   printf("  filename          The .BAT file to be interpreted.\n");
  16.   printf("  args              Any number of arguments for the batch file.\n");
  17.   exit(EXIT_FAILURE);;
  18. }
  19.  
  20. /* ---------------------------------------------------------------------- */
  21.  
  22. /*
  23.  * Setup sets up all system dependent variables. Later, when #ifdef is working
  24.  * this will be replaced using that.
  25.  */
  26.  
  27. search_path = "";       // make it global
  28. errorlevel = 0;
  29. echo = 1;               // echo on
  30.  
  31.  
  32. setup()
  33. {
  34.   if( defined(_NWNLM_) )
  35.     {
  36.       search_path = "SYS:/CENVI/";
  37.     } else {
  38.       if( defined(CMMPATH) ) search_path = CMMPATH;
  39.     }
  40. }
  41.  
  42. /*
  43.  * Change the current directory to the given one. Return 0 if successful.
  44.  */
  45. my_chdir(newdir)
  46. {
  47.   if( defined(_NWNLM_) ) return chdir(newdir);
  48.   if( defined(_DOS_) || defined(_DOS32_) || defined(_WINDOWS_) )
  49.     {
  50.       lReg.ah = 0x3B;
  51.       if !defined(_DOS32_)
  52.          lReg.ds = segment(newdir), lReg.dx = offset(newdir);
  53.       else
  54.          lReg.dx = pointer(newdir);
  55.       interrupt(0x21,lReg,out);
  56.  
  57.       return out.ax;
  58.     }
  59.   if( defined(_NTCON_) || defined(_NTWIN_) )
  60.     {
  61.       return !DynamicLink("KERNEL32","SetCurrentDirectoryA",STDCALL,newdir);
  62.     }
  63.   if( defined(_OS2_) )
  64.     {
  65. #define ORD_DOS32SETCURRENTDIR   255
  66.       return DynamicLink("doscalls",ORD_DOS32SETCURRENTDIR,BIT32,CDECL,newdir);
  67.     }
  68. }
  69.  
  70. special_command = "__@%*&^%";
  71.  
  72. /* ---------------------------------------------------------------------- */
  73.  
  74. /*
  75.  * The count is the number of params, the array is the params. These
  76.  * correspond to %X where X is a digit. We also do %variable% for environment
  77.  * variables, all uppercase.
  78.  *
  79.  * To ease processing, we kill the '\n' too.
  80.  */
  81. substitute_line(line,count,array)
  82. {
  83.   it = ""; i = 0; j = 0;
  84.   while( line[i] )
  85.     {
  86.       if( line[i]!='%' )
  87.         {
  88.           if( line[i]!='\n' )
  89.             {
  90.               it[j++] = line[i];
  91.             }
  92.           i++;
  93.           continue;
  94.         }
  95. // Here we have a substitution...
  96.       if( isdigit(line[i+1]) )
  97.         {
  98.           i += 2;
  99.           num = line[i-1]-'0';
  100.           if( num>=count ) continue;     // no such argument
  101.           for( k=0;array[num][k];k++ ) it[j++] = array[num][k];
  102.         } else {
  103.           if( line[++i]=='%' )
  104.             {
  105.               i++; it[j++] = '%'; continue;
  106.             }
  107.  
  108.           env = ""; offset = 0;
  109.           for( ;line[i] && !isspace(line[i]) && line[i]!='%';i++ )
  110.             env[offset++] = line[i];
  111.  
  112.           if( isspace(line[i]) )
  113.             {
  114.               printf("Variable is not terminated.\n");
  115.               return "";
  116.             }
  117.  
  118.           env[offset] = 0; i++;
  119.           value = "";
  120.           sprintf(to_exec,"if( DataType(%s)==CMM_INT ) sprintf(value,\"%%d\",%s); else if( DataType(%s)==CMM_BYTE ) strcpy(value,%s);\n",env,env,env,env);
  121.           Interpret(to_exec,INTERP_TEXT);
  122.           while( value[0]!='\0' ) { it[j++] = value[0]; value++; }
  123.         }
  124.     }
  125.   it[j] = '\0';
  126.   return it;
  127. }
  128.  
  129. /*
  130.  * Search the appropriate places for the given name. If found, return the
  131.  * full filename else return NULL.
  132.  */
  133. find_cmm(name)
  134. {
  135. // First search the exact filename
  136.   if( fp = fopen(name,"r") )
  137.     {
  138.       fclose(fp);
  139.       return FullPath(name);
  140.     }
  141.  
  142. // Then search the filename converted to '.cmm'
  143.   path = SplitFileName(name);
  144.   sprintf(newname,"%s%s.cmm",path.dir,path.name);
  145.   if( fp = fopen(newname,"r") )
  146.     {
  147.       fclose(fp);
  148.       return FullPath(newname);
  149.     }
  150.  
  151. // Then search the converted filename using the search path.
  152.   strcpy(tmppath,search_path);
  153.   while( tmppath[0]!='\0' )
  154.     {
  155.       while( tmppath[0]==';' ) tmppath++;
  156.       start = tmppath;
  157.       while( tmppath[0]!='\0' && tmppath[0]!=';' ) tmppath++;
  158.       tmppath[0] = '\0'; tmppath++;
  159.       sprintf(newname,"%s%c%s.cmm",start,strchr(start,'/')?'/':'\\',path.name);
  160.       if( fp = fopen(newname,"r") )
  161.         {
  162.           fclose(fp);
  163.           return FullPath(newname);
  164.         }
  165.     }
  166.  
  167. // Else not found
  168.   return NULL;
  169. }
  170.  
  171. /* ---------------------------------------------------------------------- */
  172.  
  173. next_token(line,index)
  174. {
  175.   command = ""; j = 0;
  176.   while( isspace(line[index]) ) index++;
  177.   while( line[index] && !isspace(line[index]) )
  178.     command[j++] = line[index++];
  179.   while( isspace(line[index]) ) index++;
  180.   command[j] = '\0';
  181.   return command;
  182. }
  183.  
  184. /* ---------------------------------------------------------------------- */
  185.  
  186. // All these functions return the name of the label we have to GOTO, or ""
  187. // if none.
  188.  
  189.  
  190. /*
  191.  * We just ignore the line.
  192.  */
  193. REM_handler(the_line,ptr,line_num)
  194. {
  195.   return "";
  196. }
  197.  
  198.  
  199.  
  200. /*
  201.  * We dump the text to the terminal. The exceptions are if we have 'echo on'
  202.  * or 'echo off'.
  203.  */
  204. ECHO_handler(the_line,ptr,line_num)
  205. {
  206.   if( !stricmp(the_line+ptr,"ON") )
  207.     {
  208.       echo = 1;
  209.       return "";
  210.     }
  211.   if( !stricmp(the_line+ptr,"OFF") )
  212.     {
  213.       echo = 0;
  214.       return "";
  215.     }
  216.  
  217.   printf("%s\n",the_line+ptr);
  218.   return "";
  219. }
  220.  
  221.  
  222.  
  223. /*
  224.  * If no parameter, print the current directory. Otherwise, set the current
  225.  * directory to what is given.
  226.  */
  227. CD_handler(the_line,ptr,line_num)
  228. {
  229.   if( the_line[ptr]=='\0' )
  230.     {
  231.       printf("%s\n",getcwd(buffer));
  232.       return "";
  233.     }
  234.   if( my_chdir(the_line+ptr) )
  235.     printf("The system cannot find the path specified at line %d.\n",line_num);
  236.   return "";
  237. }
  238.  
  239.  
  240. /*
  241.  * Simply clear the screen.
  242.  */
  243. CLS_handler(the_line,ptr,line_num)
  244. {
  245.   ScreenClear();
  246.   return "";
  247. }
  248.  
  249.  
  250. /*
  251.  * TYPE a file to the terminal. This is an incredibly simple routine. Use
  252.  * MORE for some options.
  253.  */
  254. TYPE_handler(the_line,ptr,line_num)
  255. {
  256.   if( fp = fopen(the_line+ptr,"r") )
  257.     {
  258.       while( 1 )
  259.         {
  260.           if( (newline = fgets(fp))==NULL ) break;
  261.           printf("%s",newline);
  262.         }
  263.       fclose(fp);
  264.     } else {
  265.       printf("Unable to open file \"%s\" at line %d.\n",the_line+ptr,line_num);
  266.     }
  267.   return "";
  268. }
  269.  
  270.  
  271.  
  272. /*
  273.  * Since the variable we need to change is a local to one of our callers,
  274.  * we pass back a command to it to tell it to do what we want.
  275.  */
  276. SHIFT_handler(the_line,ptr,line_num)
  277. {
  278.   return special_command;
  279. }
  280.  
  281.  
  282.  
  283. /*
  284.  * Just waits for the user to press any key.
  285.  */
  286. PAUSE_handler(the_line,ptr,line_num)
  287. {
  288.   printf("Press any key when ready . . . "); fflush(stdout);
  289.   getch();
  290.   printf("\n");
  291.   return "";
  292. }
  293.  
  294.  
  295.  
  296. /*
  297.  * Invoke a new batch file and return to this one when it finishes
  298.  */
  299. CALL_handler(the_line,ptr,line_num)
  300. {
  301. // Set up a new argc/argv array and call main again.
  302.   strcpy(newargv[0],"CEnvi");
  303.   newargc = 1;
  304.   while( the_line[ptr]!='\0' )
  305.     {
  306.       command = next_token(the_line,ptr);
  307.       strcpy(newargv[newargc++],command);
  308.       while( isspace(the_line[ptr]) ) ptr++;
  309.     }
  310.   main(newargc,newargv);
  311.   return "";
  312. }
  313.  
  314.  
  315.  
  316. /*
  317.  * The _EVIL_ goto command...
  318.  */
  319. GOTO_handler(the_line,ptr,line_num)
  320. {
  321.   return the_line+ptr;
  322. }
  323.  
  324.  
  325.  
  326. /*
  327.  * No, this does not simulate a person skilled in dealing with evil
  328.  * Egyptian gods...
  329.  */
  330. SET_handler(the_line,ptr,line_num)
  331. {
  332.   if( defined(_NWNLM_) )
  333.     {
  334.       printf("Netware has no environment variables at line %d.\n",line_num);
  335.       return "";
  336.     }
  337.  
  338.   if( the_line[ptr]=='\0' )
  339.     {
  340.       array = getenv();
  341.       for( ii=0;ii<GetArraySpan(array);ii++ )
  342.         {
  343.           printf("%s=%s\n",array[ii],getenv(array[ii]));
  344.         }
  345.       return "";
  346.     }
  347.  
  348. // Else we extract the name and see if we have a '=' or not.
  349.   command = next_token(the_line,ptr);
  350.  
  351.   if( (where = strchr(command,'='))!=NULL )
  352.     {
  353.       where[0] = '\0';
  354.       strcpy(env_var,command);
  355.       strcpy(new_val